/*
 * Event.h
 *
 *	Author: stravant
 *	Description:
 *		
 */

#ifndef EVENT_H_
#define EVENT_H_

#include "../core/Vec.h"
#include "../ui/KeySysm.h"

namespace tbt {

/*
 * Mouse button defining enum
 */
namespace Mouse {
enum Button {
	kButtonRight,
	kButtonCenter,
	kButtonLeft,
	kButtonMax,
};
}



/*
 * class Event
 *  Base event class, containing flags and type
 */
class Event {
public:
	enum Type {
		kEvtMouseMove,
		kEvtMouseEnter,
		kEvtMouseLeave,
		//
		kEvtMouseDown,
		kEvtMouseUp,
		kEvtMouseWheel,
		//
		kEvtKeyDown,
		kEvtKeyUp,
		kEvtKeyTyped,
		//
		kEvtDropped,
		kEvtCustom,
		//
		kEvtMax,
	};

	enum Flag {
		kFlagKeyCaps		= (1<<0),
		kFlagKeyShift		= (1<<1),
		kFlagKeyAlt			= (1<<2),
		kFlagKeyCtrl		= (1<<3),
		kFlagKeyCmd			= (1<<4),
		kFlagMouseRight		= (1<<5),
		kFlagMouseLeft		= (1<<6),
		kFlagMouseCenter	= (1<<7),
	};

	Flag getFlags() const {
		return mFlags;
	}

	void setFlags(Flag flags) {
		mFlags = flags;

	}

	Type getType() const {
		return mType;
	}

	bool shiftKeyDown() const {return (mFlags & kFlagKeyShift) != 0;}
	bool ctrlKeyDown() const {return (mFlags & kFlagKeyCtrl) != 0;}
	bool altKeyDown() const {return (mFlags & kFlagKeyAlt) != 0;}
	bool capsKeyDown() const {return (mFlags & kFlagKeyCaps) != 0;}

protected:
	Event(Type ty, Flag flags = (Flag)0): mType(ty), mFlags(flags) {}
	virtual ~Event() {}

private:
	Type mType;
	Flag mFlags;
};


/*
 * class LocatedEvent
 *  Base event class for events which contain an active position
 */
class LocatedEvent: public Event {
public:
	const IVec& getPos() const {return mPos;}
	int getX() const {return mPos.x();}
	int getY() const {return mPos.y();}

protected:
	LocatedEvent(Event::Type ty, Event::Flag flags, const IVec& pos):
		Event(ty, flags), mPos(pos) {}

private:
	IVec mPos;
};


/*
 * class MouseEvent
 *  Mouse event base
 */
class MouseEvent: public LocatedEvent {
public:
	enum MouseEventFlag {
		kFlagDoubleClick,
		kFlagTripleClick,
	};

	MouseEvent(Event::Type ty, Event::Flag flags, const IVec& pos):
		LocatedEvent(ty, flags, pos) {}

	bool leftButtonDown() const {return (getFlags() & kFlagMouseLeft) != 0;}
	bool rightButtonDown() const {return (getFlags() & kFlagMouseRight) != 0;}
	bool middleButtonDown() const {return (getFlags() & kFlagMouseCenter) != 0;}
};


/*
 * final class MouseButtonEvent
 *  Mouse pressed or released
 */
class MouseButtonEvent: public MouseEvent {
public:
	MouseButtonEvent(Event::Type ty, Event::Flag flags, Mouse::Button which, const IVec& pos):
		MouseEvent(ty, flags, pos), mButton(which) {}

	Mouse::Button getButton() const {
		return mButton;
	}
private:
	Mouse::Button mButton;
};


/*
 * final class KeyEvent
 *  Key pressed or released
 */
class KeyEvent: public Event {
public:
	KeyEvent(Event::Type ty, Event::Flag flags, Key::Code keycode):
		Event(ty, flags), mCode(keycode) {}

	Key::Code getKeycode() const {
		return mCode;
	}
private:
	Key::Code mCode;
};


/*
 * final class MouseWheelEvent
 *  Mouse wheel scrolled
 */
class MouseWheelEvent: public LocatedEvent {
public:
	MouseWheelEvent(Event::Type ty, Event::Flag flags, const IVec& pos, int delta):
		LocatedEvent(ty, flags, pos), mDelta(delta) {}

	int getDelta() const {
		return mDelta;
	}
private:
	int mDelta;
};

}

#endif /* EVENT_H_ */





















